package net.csdn.business.discuss.api.service.impl;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import net.csdn.business.discuss.api.config.ApiConfigData;
import net.csdn.business.discuss.api.config.DiscussConfigData;
import net.csdn.business.discuss.api.mapper.DiscussCategoryMapper;
import net.csdn.business.discuss.api.model.dto.*;
import net.csdn.business.discuss.api.model.entity.DiscussCategory;
import net.csdn.business.discuss.api.model.query.DiscussCategoryQuery;
import net.csdn.business.discuss.api.model.vo.CategoryTypeVO;
import net.csdn.business.discuss.api.model.vo.DiscussCategoryVO;
import net.csdn.business.discuss.api.model.vo.DiscussSectionVO;
import net.csdn.business.discuss.api.service.IDiscussAsyncService;
import net.csdn.business.discuss.api.service.IDiscussCategoryService;
import net.csdn.business.discuss.api.service.IDiscussSectionService;
import net.csdn.business.discuss.common.constant.RedisConstants;
import net.csdn.business.discuss.common.enums.ResultCodeEnum;
import net.csdn.business.discuss.common.exception.BusinessException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;


/**
 * 讨论分类Service业务层处理
 * 
 * @author Admin Cloud
 * @date 2023-07-15
 */
@Slf4j
@Service
public class DiscussCategoryServiceImpl extends ServiceImpl<DiscussCategoryMapper, DiscussCategory> implements IDiscussCategoryService
{

    @Autowired
    private ApiConfigData apiConfigData;

    @Autowired
    private CacheManager cacheManager;

    @Autowired
    private IDiscussAsyncService discussAsyncService;

    @Autowired
    private IDiscussSectionService discussSectionService;

    @Autowired
    private DiscussConfigData discussConfigData;

    @Override
    public List<CategoryTypeVO> getTypeList() {
        return discussConfigData.getCategoryType();
    }

    /**
     * 分页查询讨论分类列表
     *
     * @param query 讨论分类
     * @return 讨论分类
     */
    @Override
    public IPage<DiscussCategoryVO> findPageList(DiscussCategoryQuery query) {
        //获得Page对象
        Page<DiscussCategoryVO> page = query.getPage();
        List<DiscussCategoryVO> pageList=baseMapper.findPageList(page,query);
        page.setRecords(pageList);
        return page;
    }

    /**
     * 根据id查询讨论分类
     * 
     * @param id 讨论分类主键
     * @return 讨论分类
     */
    @Override
    public DiscussCategoryVO selectDiscussCategoryById(String id)
    {
        return baseMapper.selectDiscussCategoryById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer initDiscussCategory(InitDiscussDTO params) {
        String sourceId=params.getSourceId();
        Integer sourceType=params.getSourceType();
        List<DiscussCategoryVO> categoryList=baseMapper.getListBySourceId(sourceId,sourceType);
        if(categoryList.size()>0){
            return 0;
        }
        String currUserId=params.getCurrUserId()!=null?params.getCurrUserId():"-1";
        List<DiscussCategoryVO> systemList=baseMapper.getListBySourceId("-1",2);
        if(systemList==null||systemList.size()==0){
            return 0;
        }
        List<DiscussCategory> categories=new LinkedList<>();
        systemList.stream().forEach(categoryVO->{
            String id= IdUtil.fastSimpleUUID();
            DiscussCategory entity=new DiscussCategory();
            entity.setObjectId(id);
            entity.setCategoryName(categoryVO.getCategoryName());
            entity.setCategoryIcon(categoryVO.getCategoryIcon());
            entity.setCategoryDesc(categoryVO.getCategoryDesc());
            entity.setCategoryType(categoryVO.getCategoryType());
            entity.setSourceType(sourceType);
            entity.setSourceId(sourceId);
            entity.setCreatedBy(currUserId);
            categories.add(entity);
        });
        this.saveBatch(categories);
        return 1;
    }

    @Override
    public List<DiscussCategoryVO> getListBySourceId(String sourceId,Integer sourceType) {
        return baseMapper.getListBySourceId(sourceId,sourceType);
    }

    @Override
    public Map<String, DiscussCategoryVO> getMapBySourceId(String sourceId, Integer sourceType) {
        Map<String, DiscussCategoryVO> result=null;
        List<DiscussCategoryVO> list=baseMapper.getListBySourceId(sourceId,sourceType);
        if(list==null){
            result=new HashMap<>();
            return result;
        }
        result=list.stream().collect(Collectors.toMap(item -> item.getObjectId(), item -> item, (o1, o2) -> o2));
        return result;
    }

    @Override
    public List<DiscussCategoryVO> getListBySectionId(String sectionId) {
        return baseMapper.getListBySectionId(sectionId);
    }

    @Override
    public Map<String, List> getCategoryAndSectionList(String sourceId,Integer sourceType) {
        Map<String, List> result=null;
        //查询缓存
        Cache cache=null;
        try{
            cache = cacheManager.getCache(RedisConstants.DISCUSS_CATEGORY_ALL_LIST);
            result = cache.get(sourceId, Map.class);
        }catch (Exception e){
            log.info("cache get key:{} error: {} !",sourceId,e.getMessage());
        }
        if(result!=null){
            return result;
        }
        //初始化
        InitDiscussDTO params=new InitDiscussDTO();
        params.setSourceId(sourceId);
        params.setSourceType(sourceType);
        this.initDiscussCategory(params);
        result=new LinkedHashMap<>();
        //查询未分类的目录
        List<DiscussCategoryVO> noSectionCategoryList=baseMapper.getListNoSection(sourceId);
        result.put("unSection",noSectionCategoryList);
        //查询已分类的目录
        List<DiscussSectionVO> listSection=discussSectionService.selectDiscussSectionListBySourceId(sourceId);
        listSection.stream().parallel().forEach(discussSectionVO->{
            String sectionId=discussSectionVO.getObjectId();
            List<DiscussCategoryVO>  categoryList=baseMapper.getListSectionId(sectionId);
            discussSectionVO.setCategoryList(categoryList);
        });
        result.put("section",listSection);
        try{
            cache.put(sourceId, result);
        }catch (Exception e){
            log.info("cache put key:{} error: {} !",sourceId,e.getMessage());
        }
        return result;
    }

    /**
     * 查询讨论分类列表
     * 
     * @param query 讨论分类
     * @return 讨论分类
     */
    @Override
    public List<DiscussCategoryVO> selectDiscussCategoryList(DiscussCategoryQuery query)
    {
        return baseMapper.selectDiscussCategoryList(query);
    }

    /**
     * 新增讨论分类
     * 
     * @param params 讨论分类
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String insertDiscussCategory(NewDiscussCategoryDTO params)
    {
        String sourceId=params.getSourceId();
        //验证category的名称是否存在
        LambdaQueryWrapper<DiscussCategory> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DiscussCategory::getCategoryName, params.getCategoryName());
        queryWrapper.eq(DiscussCategory::getSourceId,sourceId);
        List<DiscussCategory> sections=baseMapper.selectList(queryWrapper);
        if(sections!=null&&sections.size()>0){
            throw new BusinessException(ResultCodeEnum.DISCUSS_CATEGORY_NAME_EXIST_ERROR);
        }
        //根据sourceId查询创建的分类数量
        Integer total=baseMapper.selectDiscussCategoryTotal(sourceId);
        if(total>=apiConfigData.getCategoryTotal()){
            throw new BusinessException(ResultCodeEnum.DISCUSS_CATEGORY_UP_LIMIT_ERROR);
        }
        Integer sourceType=params.getSourceType();
        String currUserId=params.getCurrUserId();
        //判断组织或项目的管理员权限
        switch (sourceType){
            case 1:
                break;
            case 2:
                break;
        }
        DiscussCategory discussCategory=new DiscussCategory();
        BeanUtils.copyProperties(params,discussCategory,"sectionId");
        String id= IdUtil.fastSimpleUUID();
        discussCategory.setObjectId(id);
        discussCategory.setCreatedBy(currUserId);
        String sectionId=params.getSectionId();
        if(StringUtils.isNotBlank(sectionId)){
            discussCategory.setSectionId(sectionId);
        }
        baseMapper.insert(discussCategory);
        Cache cache=null;
        try{
            cache = cacheManager.getCache(RedisConstants.DISCUSS_CATEGORY_ALL_LIST);
            cache.evict(sourceId);
        }catch (Exception e){
            log.info("cache evict cache name:{} error: {} !",sectionId,e.getMessage());
        }
        return id;
    }

    /**
     * 修改讨论分类
     * 
     * @param params 讨论分类
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer updateDiscussCategory(UpdateDiscussCategoryDTO params)
    {
        String id=params.getId();
        String sourceId=params.getSourceId();
        //验证category的名称是否存在
        LambdaQueryWrapper<DiscussCategory> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DiscussCategory::getCategoryName, params.getCategoryName());
        queryWrapper.eq(DiscussCategory::getSourceId,sourceId);
        queryWrapper.ne(DiscussCategory::getObjectId,id);
        List<DiscussCategory> sections=baseMapper.selectList(queryWrapper);
        if(sections!=null&&sections.size()>0){
            throw new BusinessException(ResultCodeEnum.DISCUSS_CATEGORY_NAME_EXIST_ERROR);
        }
        String currUserId=params.getCurrUserId();
        String sectionId=params.getSectionId();
        LambdaUpdateWrapper<DiscussCategory> updateWrapper = new UpdateWrapper<DiscussCategory>().lambda();
        updateWrapper.eq(DiscussCategory::getObjectId, id);
        updateWrapper.set(DiscussCategory::getCategoryName,params.getCategoryName());
        updateWrapper.set(DiscussCategory::getCategoryIcon,params.getCategoryIcon());
        updateWrapper.set(DiscussCategory::getCategoryDesc,params.getCategoryDesc());
        updateWrapper.set(DiscussCategory::getCategoryType,params.getCategoryType());
        updateWrapper.set(DiscussCategory::getLastModifiedBy,currUserId);
        if(StringUtils.isNotBlank(sectionId)){
            updateWrapper.set(DiscussCategory::getSectionId,params.getSectionId());
        }else{
            updateWrapper.set(DiscussCategory::getSectionId,null);
        }
        int result=baseMapper.update(null,updateWrapper);
        if(result>0){
            Cache cache=null;
            try{
                cache = cacheManager.getCache(RedisConstants.DISCUSS_CATEGORY_ALL_LIST);
                cache.evict(sourceId);
            }catch (Exception e){
                log.info("cache evict cache name:{} error: {} !",sectionId,e.getMessage());
            }
        }
        return result;
    }

    /**
     * 删除讨论分类信息
     *
     * @param params 删除讨论分类请求信息
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer deleteDiscussCategoryById(DeleteResourceDTO params)
    {
        String transferId=params.getTransferId();
        String sourceId=params.getSourceId();
        if(StringUtils.isBlank(transferId)){
            throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,"transferId");
        }
        Integer sourceType=params.getSourceType();
        LambdaQueryWrapper<DiscussCategory> queryWrapper = new LambdaQueryWrapper<DiscussCategory>();
        queryWrapper.eq(DiscussCategory::getObjectId, params.getId());
        //防止删除系统默认分类
        queryWrapper.ne(DiscussCategory::getSourceId,"-1");
        int result=baseMapper.delete(queryWrapper);
        //转移所属分类的讨论到另外的分类
        TransferCategoryDTO tansferParams=new TransferCategoryDTO();
        tansferParams.setId(params.getId());
        tansferParams.setTargetId(params.getTransferId());
        tansferParams.setSourceId(params.getSourceId());
        //异步转移关联资源的目录
        discussAsyncService.transferCategory(tansferParams);
        if(result>0){
            Cache cache=null;
            try{
                cache = cacheManager.getCache(RedisConstants.DISCUSS_CATEGORY_ALL_LIST);
                cache.evict(sourceId);
            }catch (Exception e){
                log.info("cache evict cache name:{} error: {} !",sourceId,e.getMessage());
            }
        }
        return  result;
    }

    @Override
    public Integer updateAuditStatus(UpdateAuditStatusDTO params) {
        LambdaUpdateWrapper<DiscussCategory> updateWrapper = new UpdateWrapper<DiscussCategory>().lambda();
        updateWrapper.eq(DiscussCategory::getObjectId, params.getId());
        updateWrapper.set(DiscussCategory::getAuditStatus, params.getAuditStatus());
        int result=baseMapper.update(null,updateWrapper);
        return result;
    }
}
